/*
 * PSPlayer.cpp
 *
 *  Created on: 2016年1月25日
 *      Author: terry
 */

#include "PSPlayer.h"
#include "TStringUtil.h"
#include "TcpJsonAVFormat.h"
#include "CLog.h"


PSPlayer::PSPlayer():
    m_tcpPs(),
    m_dict()
{
    m_tcpPs = new TcpJsonAVFormat();
}

PSPlayer::~PSPlayer()
{
    close();
}

int PSPlayer::setParam(const char* key, const char* value)
{
    return av_dict_set(&m_dict, key, value, 0);
}

int PSPlayer::open(const char* url)
{
    std::string str = comn::StringUtil::getTail(url, "://");

    std::string ip;
    int port = 0;
    comn::StringUtil::split(str, ':', ip, port);

    int rc = m_tcpPs->open(ip.c_str(), port);
    if (rc != 0)
    {
        return rc;
    }

    AVDictionaryEntry* entry = av_dict_get(m_dict, "json", NULL, 0);
    if (entry != NULL)
    {
        int rc = m_tcpPs->play(entry->value);
        if (rc != 0)
        {
            close();
            return rc;
        }
    }

    m_player.open(AV_CODEC_ID_H264, AV_CODEC_ID_AAC, 8000, 1);

    if (!isRunning())
    {
        start();
    }

    return 0;
}

void PSPlayer::close()
{
    if (isRunning())
    {
        stop();
    }

    m_player.close();

    m_tcpPs->close();

    if (m_dict)
    {
        av_dict_free(&m_dict);
    }
}

bool PSPlayer::isOpen()
{
    return m_player.isOpen();
}

void PSPlayer::setVideoWnd(HWND hwnd)
{
    m_player.setVideoWnd(hwnd);
}

int PSPlayer::run()
{
    static const size_t MAX_BUF_SIZE = 1024 * 8;
    uint8_t buf[MAX_BUF_SIZE];

    while (!m_canExit)
    {
        int length = m_tcpPs->read(buf, MAX_BUF_SIZE);
        if (length == 0)
        {
            continue;
        }
        else if (length < 0)
        {
            onStreamEnd();
            break;
        }

        onRead(buf, length);
    }
    return 0;
}

void PSPlayer::doStop()
{
    m_event.post();

    if (m_tcpPs)
    {
        m_tcpPs->close();
    }
    
}

void PSPlayer::onRead(uint8_t* buf, int length)
{
    //CLog::debug("onRead size:%d\n", length);
    av::ProgramStreamParser::StreamPacket pkt;
    while (m_psParser.inputData(buf, length, pkt))
    {
        MediaPacket mpkt;
        memset(&mpkt, 0, sizeof(mpkt));
        mpkt.data = pkt.data;
        mpkt.size = pkt.length;
        mpkt.type = MEDIA_TYPE_VIDEO;

        m_player.input(mpkt);

        buf = NULL;
        length = 0;
    }
}

void PSPlayer::onStreamEnd()
{
    CLog::info("stream end.\n");
}